import { ArgumentMetadata, PipeTransform , BadRequestException} from '@nestjs/common';

import {
  plainToInstance, // 将普通对象转换为类的实例
} from 'class-transformer'

import {
  validate, // 验证对象
} from 'class-validator'

/**
 * 内置管道
 */
export class ValidationPipe implements PipeTransform {
  async transform(value: any, metadata: ArgumentMetadata) {
    // 如果路由处理函数的参数没有类型 或 内置的类型 不需要验证
    if (!metadata.metatype || this.needValidate(metadata.metatype)) return value;
    const instance = plainToInstance(metadata.metatype, value) // 将普通对象转换为类(metadata.metatype)的实例
    const errors = await validate(instance) // 验证对象
    if (errors.length > 0) { // 验证失败
      console.log('errors ', this.formatErrors(errors))
      throw new BadRequestException('Validation failed') // 会被异常过滤器捕获并处理
    }
    return value;
  }

  /**
   * 内置的类型不需要验证
   */
  private needValidate(metatype: Function) {
    const types: Function[] = [String, Boolean, Number, Array, Object, Function]
    return types.includes(metatype)
  }

  /**
   * 格式化错误
   */
  private formatErrors(errors) {
    return errors.map(error => {
      for (const property in error.constraints) {
        return `${error.property} - ${error.constraints[property]}`
      }
    }).join(',')
  }
}
